package com.mcp.weather;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mcp.weather.config.Config;
import com.mcp.weather.model.WeatherResponse;
import com.mcp.weather.service.AmapWeatherService;
import com.mcp.weather.util.JsonRpcHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.Executors;

/**
 * 主入口类
 */
public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    private static final ObjectMapper objectMapper = JsonRpcHandler.getObjectMapper();

    public static void main(String[] args) {
        Config config = new Config();
        WeatherMcpServer server = new WeatherMcpServer(config);

        // 启动 HTTP 测试服务器（如果配置了 HTTP_PORT）
        if (config.getHttpPort() != null) {
            startHttpServer(config, server);
        }

        // 启动 stdio 主循环
        runStdioLoop(server);
    }

    /**
     * 启动 HTTP 测试服务器
     */
    private static void startHttpServer(Config config, WeatherMcpServer mcpServer) {
        try {
            // 获取天气服务实例（共享缓存）
            AmapWeatherService weatherService = mcpServer.getWeatherService();
            
            HttpServer httpServer = HttpServer.create(new InetSocketAddress(config.getHttpPort()), 0);
            httpServer.createContext("/weather", new WeatherHttpHandler(weatherService));
            httpServer.setExecutor(Executors.newFixedThreadPool(10));
            httpServer.start();
            
            logger.info("[mcp-weather-java] HTTP test server listening on http://localhost:{}", config.getHttpPort());
            // 输出到 stderr，避免干扰 stdout 的 MCP 协议
            System.err.println("[mcp-weather-java] HTTP test server listening on http://localhost:" + config.getHttpPort());
        } catch (IOException e) {
            logger.error("启动 HTTP 服务器失败", e);
            System.err.println("启动 HTTP 服务器失败: " + e.getMessage());
        }
    }

    /**
     * 运行 stdio 主循环
     */
    private static void runStdioLoop(WeatherMcpServer server) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
             OutputStream output = System.out) {
            
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.trim().isEmpty()) {
                    continue;
                }

                try {
                    // 检查是否是 initialize 请求
                    boolean isInitialize = false;
                    try {
                        JsonNode request = objectMapper.readTree(line);
                        if (request.has("method") && "initialize".equals(request.get("method").asText())) {
                            isInitialize = true;
                        }
                    } catch (Exception e) {
                        // 忽略解析错误，继续处理
                    }
                    
                    String response = server.handleRequest(line);
                    if (response != null) {
                        logger.info("Sending response: {}", response);
                        output.write((response + "\n").getBytes(StandardCharsets.UTF_8));
                        output.flush();
                        
                        // 如果是 initialize 请求，发送 initialized 通知
                        if (isInitialize) {
                            ObjectNode notification = objectMapper.createObjectNode();
                            notification.put("jsonrpc", "2.0");
                            notification.put("method", "notifications/initialized");
                            notification.set("params", objectMapper.createObjectNode());
                            String notificationStr = objectMapper.writeValueAsString(notification);
                            output.write((notificationStr + "\n").getBytes(StandardCharsets.UTF_8));
                            output.flush();
                        }
                    }
                } catch (Exception e) {
                    logger.error("处理请求失败", e);
                    // 错误日志输出到 stderr
                    System.err.println("处理请求失败: " + e.getMessage());
                }
            }
        } catch (IOException e) {
            logger.error("读取输入流失败", e);
            System.err.println("读取输入流失败: " + e.getMessage());
        }
    }

    /**
     * HTTP 请求处理器
     */
    private static class WeatherHttpHandler implements HttpHandler {
        private final AmapWeatherService weatherService;

        public WeatherHttpHandler(AmapWeatherService weatherService) {
            this.weatherService = weatherService;
        }

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            if (!"GET".equals(exchange.getRequestMethod())) {
                sendErrorResponse(exchange, 405, "Method Not Allowed");
                return;
            }

            URI uri = exchange.getRequestURI();
            String query = uri.getQuery();
            
            if (query == null || query.isEmpty()) {
                sendErrorResponse(exchange, 400, "city 为必填");
                return;
            }

            // 解析查询参数
            String city = null;
            String extensions = "base";
            
            String[] params = query.split("&");
            for (String param : params) {
                String[] keyValue = param.split("=", 2);
                if (keyValue.length == 2) {
                    String key = java.net.URLDecoder.decode(keyValue[0], StandardCharsets.UTF_8);
                    String value = java.net.URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
                    
                    if ("city".equals(key)) {
                        city = value;
                    } else if ("extensions".equals(key)) {
                        extensions = value;
                    }
                }
            }

            if (city == null || city.trim().isEmpty()) {
                sendErrorResponse(exchange, 400, "city 为必填");
                return;
            }

            if (!extensions.equals("base") && !extensions.equals("all")) {
                sendErrorResponse(exchange, 400, "extensions 仅支持 base 或 all");
                return;
            }

            // 调用天气服务
            WeatherResponse response = weatherService.queryWeather(city, extensions);

            // 发送响应
            exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8");
            
            // 检查是否有错误（通过 raw 字段判断）
            if (response.getRaw() != null && response.getRaw() instanceof WeatherResponse.ErrorResponse) {
                // 错误响应
                WeatherResponse.ErrorResponse error = (WeatherResponse.ErrorResponse) response.getRaw();
                byte[] errorBytes = objectMapper.writeValueAsBytes(error);
                exchange.sendResponseHeaders(500, errorBytes.length);
                try (OutputStream os = exchange.getResponseBody()) {
                    os.write(errorBytes);
                }
            } else if (response.getData() == null && response.getMeta() == null) {
                // 未知错误
                exchange.sendResponseHeaders(500, 0);
                try (OutputStream os = exchange.getResponseBody()) {
                    ObjectMapper mapper = JsonRpcHandler.getObjectMapper();
                    WeatherResponse.ErrorResponse error = new WeatherResponse.ErrorResponse();
                    error.setError("查询失败");
                    if (response.getQuery() != null) {
                        error.setErrorDetail(new WeatherResponse.ErrorDetail());
                        error.getErrorDetail().setProvider("amap");
                    }
                    os.write(mapper.writeValueAsBytes(error));
                }
            } else {
                // 成功响应
                byte[] responseBytes = objectMapper.writeValueAsBytes(response);
                exchange.sendResponseHeaders(200, responseBytes.length);
                try (OutputStream os = exchange.getResponseBody()) {
                    os.write(responseBytes);
                }
            }
        }

        private void sendErrorResponse(HttpExchange exchange, int statusCode, String message) throws IOException {
            ObjectMapper mapper = JsonRpcHandler.getObjectMapper();
            ObjectNode error = mapper.createObjectNode();
            error.put("error", message);
            byte[] responseBytes = mapper.writeValueAsBytes(error);
            
            exchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8");
            exchange.sendResponseHeaders(statusCode, responseBytes.length);
            try (OutputStream os = exchange.getResponseBody()) {
                os.write(responseBytes);
            }
        }
    }
}

